package com.simulador.server;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import javax.script.ScriptException;

import com.simulador.shared.JSProteina;



/**
 * Proteina es cada una de las proteínas que el usuario podría ver en pantalla
 * @author Pablo
 *
 *¿cómo una proteína alterará el fenotipo, condiciones externas, internas?
 *
 */
public class Proteina implements Serializable{
	static int local = 0; //para el id local

	/**
	 * Pa que serialice (dicen)
	 */
	private static final long serialVersionUID = 1L;
	
	//en bases de datos
	public String ID_universal; //nombre en bases de datos "sce:YBR083W"
	public String nombre;//Nombre: el que se mostrará al usuario
	public String organismo; //(al que pertenece)
	public ArrayList<String> ubicaciones;
	public HashMap<String, Boolean> modPos; //Modificaciones postraducionales String: Sitio=(fosforilacion en treonina 322) Boolean: true= fosforilado
	public ArrayList<Accion> acciones;//TODO
	public ArrayList<String> rioAbajo; // ID_u de las proteínas rio abajo
	public ArrayList<String> rioArriba; //no es una lista de proteínas porque no sabe que proteínas ya han sido creadas ni su referencia
			
//Generados
	int ID_local; //identificador (varias ubicaciones en la celula, se crea una iteración de la prot por c/lugar) 
	int posX, posY; //,posZ; Ubicación en pantalla, tomar en cuenta posiciones guardadas por el usuario
	boolean expresando;
	
	//Visibilidad
	boolean visible; // 
	double transparencia; //(ortologos) (No expresando) (proteinas de importancia lejana)
	String color; //255,0,0
	String shape; //para CanvasX square sphere star
	int size;
	
	//Al dar click debe mostrar toda la información y dar opciones de mutantes, 
	//visibilidad (si o no) y de corregir la info para la base de datos
	
	//METODOS
	/**
	 * CONSTRUCTOR
	 * @param protID idUniversal
	 * @param visibl
	 * @param transparente
	 */
	public Proteina(String protID, boolean visibl, double transparente) {
		ID_universal = protID;
		nombre = DB.getNombre(protID);
		organismo = DB.getOrganismo(protID);
		ubicaciones = DB.getUbicaciones(protID);
		modPos = DB.getModPos(protID);
		acciones = DB.getAcciones(protID);
		rioAbajo = DB.getRioAbajo(protID);
		rioArriba = DB.getRioArriba(protID);
		
		ID_local = local;
		local++;
		
		posX = 0; //llamada recursiva? 
		posY = 0; //después de crearlas ya ordenarlas
		
		expresando = true; //Hasta que vea como meterle expresión
		visible = visibl;//En que caso no se requiere ver?
		transparencia = transparente;
		color ="255,0,0";
		shape = "circle";
		size = 2;
	}
	
	//TODO public Proteína(Proteína clon){
	
	//TODO public Proteína( todo sin consultar DB){
	
	/**
	 * Devuelve un objeto JSON en String para un nodo de CanvasXpress
	 * @return el nodo
	 */
	public String nodoJSON(){ 
		String json="{id: '"  +ID_local							+"', "+ 
					"name: '"+ID_universal						+"', "+
					"label: '"+nombre							+"', "+
					"color: 'rgba("+ color +","+ transparencia 	+")', "+
					"shape: '"+shape							+"', "+
					"size: '" +size								+"'}";
		return json; 
	}
	
	public String edgeJSON(Proteina prot2){
		String edge="{id1: '"  + ID_local+"', "+
					"id2: '"  + prot2.ID_local+"', "+
					"color: '"+"rgb(51,12,255)"+ "', "+
					"width: '"+"2"+"', "+
					"type: '" +"line"+"'}";
		return edge;
	}

	

	/**
	 * realiza las acciones que correspondan 
	 * @throws ScriptException 
	 */
	public void ejecutar() throws ScriptException{
		for(int i=0; i<acciones.size(); i++){
			acciones.get(i).ejecutar();
		}
	}

	/**
	 * ID_universal getter
	 * @return ID_universal
	 */
	public String getID_universal() {
		return ID_universal;
	}

	/**
	 * Restablece el estado de la modif post 
	 * @param sit: el sitio de la modif post (este no debe cambiar, cierto? 
	 * 			agregaría una nueva modPos, que regresaría?)
	 * @param edo: el nuevo estado de la modif post
	 * @return el estado de la modPos antes de cambiar
	 */
	public boolean setModPos(String sit, boolean edo) {
		//if(sit existe ya en el hash){ else{error}
		if(modPos.get(sit) == null){
			System.err.println("error: se intenta cambiar una modificacion que no existía");
		}
		return modPos.put(sit, edo);
	}

	/**
	 * Devuelve el valor booleano de una modificació particular
	 * @param key
	 * @return
	 */
	public Boolean getModPost(String key) {
		return modPos.get(key);
	}
	
	
	//////////De Java a JS y de regreso/////////////////////////////////////////////////////

	public JSProteina toJSProteina() {	
		return new JSProteina().nueva(ID_universal, nombre, organismo, ubicaciones, modPos, rioArriba, rioAbajo);
	}

	
	public void editar(JSProteina p){
		ID_universal = p.ID_universal;
		nombre = p.nombre;
		organismo = p.organismo;
		ubicaciones = p.ubicaciones;
		modPos = p.modPos;
		//acciones = ; TODO
		rioAbajo = p.rioAbajo;
		rioArriba = p.rioArriba;
	}

	

}
